﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Framework.Infrastructure.IoC;
using System.Web.Mvc;
using System.Reflection;
using Framework.Infrastructure.ControllerFactories;
using Microsoft.Practices.Unity;

namespace Framework.BootStrappers
{
    public class WebMvcBootStrapper : BootStrapper
    {
        #region IBootStrapper Members

        /// <summary>
        /// <see cref="M:NLayerApp.Presentation.Web.MVC.Client.Extensions.BootStrapper.IBootStrapper.Boot"/>
        /// </summary>
        public override void Boot()
        {
            //Register controllers into MVC infrastructure
            base.Boot();
            RegisterControllers();

            //Register new model binders
            RegisterModelBinders();

            //register factories
            RegisterFactories();
        }

        #endregion

        #region Private Methods

        private void RegisterFactories()
        {
            //Create a custom controller factory to resolve controllers with IoC container
            IControllerFactory factory = new IoCControllerFactory(_CurrentContainer);

            //Set new controller factory in ASP.MVC Controller builder
            ControllerBuilder.Current.SetControllerFactory(factory);
        }

        protected virtual void RegisterModelBinders()
        {
            //Register a new model binder for customers. This model binder enables the deserialization
            //of a given customer in edit scenarios.
            //ModelBinders.Binders.Add(typeof(Customer), new SelfTrackingEntityModelBinder<Customer>());


            ////Register a new model binder for customer's picture. This model binder binds the posted
            ////image to a the byte array field in the CustomerPicture class.
            //ModelBinders.Binders.Add(typeof(CustomerPicture), new CustomerPictureModelBinder());
        }

        private void RegisterControllers()
        { 
            //In this implementations only controllers in same assembly are registered in IoC container. If you
            // have controllers in a different assembly check this code.

            //Recover excuting assembly.
            var assemblies = GetRegisterAssemblies();
            foreach (var assembly in assemblies)
            {  
                IEnumerable<Type> controllers = assembly.GetExportedTypes()
                                                    .Where(x => typeof(IController).IsAssignableFrom(x));

                //Register all controllers types
                foreach (Type item in controllers)
                    _CurrentContainer.RegisterType(item);
            }
            //Recover all controller types in this assembly.
          
        }

        #endregion 
    }
}
